﻿
using 开放封闭原则.终极版;

Console.WriteLine("开放封闭原则!");
/*
 开放封闭原则是面向对象所有原则的核心。
 对功能扩展开放，面向修改代码封闭。
 需求改变时，在小改变软件实体源代码（类、接口、方法等）的前提下通过扩展功能吗，使其满足新的需求。
 */
/*
 需求：描述不同需求的用户去银行办理不同的业务
1、在这段程序中 会由多少个对象
2、每个对象的属性和行为
对象1： 用户：属性记录不同类型的用户（存钱、取钱、转账....）
对象2： 银行专员：帮助我们用户处理不同的需求
对象3： 银行业务系统：处理存钱、取钱、转账等需求的操作系统 
 */


BankClient bankClient = new BankClient();
bankClient.BankType = "存款";
BankStuff bankStuff=new BankStuff();
bankStuff.HandleProcess(bankClient);
// 结论  虽然满足需求，不符合开放封闭原则。增加功能需要对内修改

BankClient bankClient2 = new BankClient();
bankClient2.BankType = "取款";
BankStuff bankStuff2 = new BankStuff();
bankStuff2.HandleProcess(bankClient2);
// 升级版  抽取接口  面向抽象/接口编程

//在类中 类的每一个方法都抽象成接口都比较极端，需根据业务进行合理的封装
//终极版
BankClient bankClient3 = new BankClient();
bankClient3.BankType = "取款";
BankStuff3 bankStuff3 = new BankStuff3();
bankStuff3.HandleProcess(bankClient3);
//解决switch case问题 封装不是目的，只有 封装变化 才能做到单一职责 ，开放封闭等原则
IBankClient bankClient4=new BuyJiJinClient(); //变化点  需要特别注意  //DepositeClient
new BankStuff4().HandleProcess(bankClient4);
public class BankClient
{
    public string?  BankType { get; set; }
}
public class BankStuff
{
    private BankProcess bankProcess =new BankProcess();
    public void HandleProcess(BankClient bankClient)
    {
       
        //调用银行的业务系统，处理我们用户的需求；
        switch (bankClient.BankType)
        {
            case "存款":
                bankProcess.Deposite();
                break;
            case "取款":
                bankProcess.DrowMoney();
                break;
            case "转账":
                bankProcess.Transfer();
                break;
            case "购买基金":
                bankProcess.BuyJiJin();
                break;
            default:
                break;
        }
    }
}
public class BankProcess
{ 
  public void Deposite()
    {
        Console.WriteLine("处理用户的存款");
    }
    public void DrowMoney()
    {
        Console.WriteLine("处理用户的取款");
    }
    public void Transfer()
    {
        Console.WriteLine("处理用户的转账");
    }
    public void BuyJiJin()
    {
        Console.WriteLine("处理用户的购买基金");
    }
}